package com.ttc.group2.videochat.activity;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.quickblox.auth.QBAuth;
import com.quickblox.core.QBCallbackImpl;
import com.quickblox.core.result.Result;
import com.quickblox.users.QBUsers;
import com.quickblox.users.model.QBUser;
import com.quickblox.users.result.QBUserResult;
import com.ttc.group2.videochat.R;
import com.ttc.group2.videochat.utils.Utils;

public class SignUpActivity extends Activity {
	private EditText etFullName;
	private EditText etUserName;
	private EditText etPassword;
	private EditText etConfirmPassword;
	private EditText etEmail;
	private TextView tvErrFullName;
	private TextView tvErrUserName;
	private TextView tvErrPassword;
	private TextView tvErrConfirmPassword;
	private TextView tvErrEmail;
	private Button btnSignUp;
	private Button btnCancel;
	private ProgressDialog progressDialog;

	private boolean isFullNameValid = false;
	private boolean isUserNameValid = false;
	private boolean isPasswordValid = false;
	private boolean isConfirmPasswordValid = false;
	private boolean isEmailValid = false;

	private boolean isUserAvailable = false;
	private boolean isEmailAvailable = false;
	private boolean isCheckOutUser = false;
	private boolean isCheckOutEmail = false;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.sign_up_layout);
		getView();
		setView();
	}


	private void getView() {
		// TODO Auto-generated method stub
		etFullName=(EditText)findViewById(R.id.etsuFullName);
		etUserName = (EditText) findViewById(R.id.etsuUserName);
		etPassword = (EditText) findViewById(R.id.etsuPassword);
		etConfirmPassword = (EditText) findViewById(R.id.etsuConfirmPassword);
		etEmail = (EditText) findViewById(R.id.etsuEmail);

		tvErrFullName = (TextView) findViewById(R.id.tvErrorFullName);
		tvErrUserName = (TextView) findViewById(R.id.tvErrorUserName);
		tvErrPassword = (TextView) findViewById(R.id.tvErrorPassword);
		tvErrConfirmPassword = (TextView) findViewById(R.id.tvErrorConfPassword);
		tvErrEmail = (TextView) findViewById(R.id.tvErrorEmail);

		btnSignUp = (Button) findViewById(R.id.btnsuSignUp);
		btnCancel = (Button) findViewById(R.id.btnsuCancel);

		progressDialog = new ProgressDialog(this);
		progressDialog.setMessage(getString(R.string.please_wait));
	}
		
	
	private void setView() {
		// TODO Auto-generated method stub
		isFullNameValid = false;
		isUserNameValid = false;
		isPasswordValid = false;
		isConfirmPasswordValid = false;
		isEmailValid = false;

		isUserAvailable = false;
		isEmailAvailable = false;

		OnFocusChangeListener onFocusChangeListener = new OnFocusChangeListener() {

			@Override
			public void onFocusChange(View v, boolean hasFocus) {
				if (!hasFocus) {
					isUserAvailable = false;
					isEmailAvailable = false;
					validation(v);
				}

			}
		};
		etFullName.setOnFocusChangeListener(onFocusChangeListener);
		etUserName.setOnFocusChangeListener(onFocusChangeListener);
		etPassword.setOnFocusChangeListener(onFocusChangeListener);
		etConfirmPassword.setOnFocusChangeListener(onFocusChangeListener);
		etEmail.setOnFocusChangeListener(onFocusChangeListener);

		OnClickListener onbtnClickListener = new OnClickListener() {

			@Override
			public void onClick(View view) {
				onbtnClick(view);
			}
		};

		btnSignUp.setOnClickListener(onbtnClickListener);
		btnCancel.setOnClickListener(onbtnClickListener);
	}

	private void onbtnClick(View view) {
		int i=view.getId();
		if(i==R.id.btnsuSignUp){
			signUp();
//			finish();
		}
		else if(i==R.id.btnsuCancel){
			finish();	
		}
		
	}

	/**
	 * Signing up user;
	 */
	private void signUp() {

		String FullName = etFullName.getText().toString();
		String UsetName = etUserName.getText().toString();
		String Password = etPassword.getText().toString();
		String Email = etEmail.getText().toString();
		if (checkValidation()) {

			final QBUser user = new QBUser(UsetName, Password);
			user.setEmail(Email);
			user.setFullName(FullName);
			QBAuth.createSession(new QBCallbackImpl() {
				@Override
				public void onComplete(Result result) {
					if (result.isSuccess()) {
						progressDialog.show();
						QBUsers.signUp(user, new QBCallbackImpl() {
							@Override
							public void onComplete(Result result) {
								if (result.isSuccess()) {
									progressDialog.dismiss();
									Utils.showToast(getApplicationContext(),
											R.string.su_success);
									finish();
								} else {
									progressDialog.dismiss();
									Utils.showToast(getApplicationContext(),
											R.string.su_failed);
									Utils.showToast(getApplicationContext(),
											result.getErrors().toString());
									Log.e("Errors", result.getErrors()
											.toString());
								}
							}
						});
					}
				}
			});
			isUserAvailable = false;
			isEmailAvailable = false;
		} else {

		}
	}

	/**
	 * validation sign up info in view
	 * 
	 * @param view
	 *            edit text view that need to be validated
	 */
	private void validation(View view) {
		int i=view.getId();
		if(i==R.id.etsuFullName){
			checkFullName((EditText) view);
		}
		else if (i==R.id.etsuUserName){
			checkUserName((EditText) view);
		}
		else if(i==R.id.etsuPassword){
			checkPassword((EditText) view);
		}
		else if(i==R.id.etsuConfirmPassword){
			checkConfirmPassword((EditText) view);
		}
		else if(i==R.id.etsuEmail){
			checkEmail((EditText) view);
		}
	}

	/**
	 * validate Full name
	 * 
	 * @param view
	 *            EditText full name
	 */
	private void checkFullName(EditText view) {
		if (view.getText().toString().length() >= Utils.FULL_NAME_LENGHT) {
			view.setBackgroundResource(R.drawable.et_valid);
			int p = (int) getResources().getDimension(R.dimen.et_padding);
			view.setPadding(p, p, p, p);
			tvErrFullName.setVisibility(View.INVISIBLE);
			isFullNameValid = true;
		} else {
			view.setBackgroundResource(R.drawable.et_error);
			int p = (int) getResources().getDimension(R.dimen.et_padding);
			view.setPadding(p, p, p, p);
			tvErrFullName.setVisibility(View.VISIBLE);
			isFullNameValid = false;
		}
	}

	/**
	 * validate user name
	 * 
	 * @param view
	 *            EditText user name
	 */
	private void checkUserName(EditText view) {
		if (!isUserAvailable) {
			checkOutUserName(view.getText().toString());
			isCheckOutUser = true;
		}
		if (view.getText().toString().length() >= Utils.USERNAME_LENGHT) {
			view.setBackgroundResource(isCheckOutUser ? R.drawable.et_waiting
					: R.drawable.et_valid);
			int p = Utils.getResourseInteger(getApplicationContext(),
					R.dimen.et_padding);
			view.setPadding(p, p, p, p);

			String msg = isCheckOutUser ? Utils.getResourseString(this,
					R.string.msg_is_checking_username_available) : "";

			tvErrUserName.setText(msg);
			tvErrUserName.setVisibility(isCheckOutUser ? View.VISIBLE
					: View.INVISIBLE);
			isUserNameValid = true;
		} else {
			view.setBackgroundResource(isCheckOutUser ? R.drawable.et_waiting
					: R.drawable.et_error);
			int p = Utils.getResourseInteger(getApplicationContext(),
					R.dimen.et_padding);
			view.setPadding(p, p, p, p);
			String msg = "";
			msg += isCheckOutUser ? Utils.getResourseString(this,
					R.string.msg_is_checking_username_available) : "";
			if (view.getText().toString().length() < Utils.USERNAME_LENGHT) {
				msg += msg.length() > 0 ? "\n" : "";
				msg += Utils.getResourseString(getApplicationContext(),
						R.string.msg_user_invalid);
			}
			tvErrUserName.setText(msg);
			tvErrUserName.setVisibility(View.VISIBLE);
			isUserNameValid = false;
		}
	}

	/**
	 * show on UI that user name is used or not
	 */
	private void showUsernameAvailable() {
		etUserName
				.setBackgroundResource(isUserAvailable && isUserNameValid ? R.drawable.et_valid
						: R.drawable.et_error);
		int p = Utils.getResourseInteger(getApplicationContext(),
				R.dimen.et_padding);
		etUserName.setPadding(p, p, p, p);

		String msg = "";
		msg += isUserAvailable ? "" : Utils.getResourseString(this,
				R.string.msg_user_unavailable);
		if (!isUserNameValid) {
			msg += msg.length() > 0 ? "\n" : "";
			msg += Utils.getResourseString(getApplicationContext(),
					R.string.msg_user_invalid);
		}
		tvErrUserName.setText(msg);
		tvErrUserName
				.setVisibility(isUserAvailable && isUserNameValid ? View.INVISIBLE
						: View.VISIBLE);
	}

	/**
	 * validate password
	 * 
	 * @param view
	 *            EditText password
	 */
	private void checkPassword(EditText view) {
		if (view.getText().toString().length() >= Utils.PASSWORD_LENGHT) {
			view.setBackgroundResource(R.drawable.et_valid);
			int p = (int) getResources().getDimension(R.dimen.et_padding);
			view.setPadding(p, p, p, p);
			tvErrPassword.setVisibility(View.INVISIBLE);
			isPasswordValid = true;
		} else {
			view.setBackgroundResource(R.drawable.et_error);
			int p = (int) getResources().getDimension(R.dimen.et_padding);
			view.setPadding(p, p, p, p);
			tvErrPassword.setVisibility(View.VISIBLE);
			isPasswordValid = false;
		}
	}

	/**
	 * validate confirm password
	 * 
	 * @param view
	 *            EditText confirm password
	 */
	private void checkConfirmPassword(EditText view) {
		if (view.getText().toString().length() >= Utils.PASSWORD_LENGHT
				&& view.getText().toString()
						.equals(etPassword.getText().toString())) {
			view.setBackgroundResource(R.drawable.et_valid);
			int p = (int) getResources().getDimension(R.dimen.et_padding);
			view.setPadding(p, p, p, p);
			tvErrConfirmPassword.setVisibility(View.INVISIBLE);
			isConfirmPasswordValid = true;
		} else {
			view.setBackgroundResource(R.drawable.et_error);
			int p = (int) getResources().getDimension(R.dimen.et_padding);
			view.setPadding(p, p, p, p);
			tvErrConfirmPassword.setVisibility(View.VISIBLE);
			isConfirmPasswordValid = false;
		}
	}

	/**
	 * validate user email
	 * 
	 * @param view
	 *            EditText email
	 */
	private void checkEmail(EditText view) {
		if (!isEmailAvailable) {
			checkOutEmail(view.getText().toString());
			isCheckOutEmail = true;
		}
		if (validEmailForm(view.getText().toString())) {
			view.setBackgroundResource(isCheckOutEmail ? R.drawable.et_waiting
					: R.drawable.et_valid);
			int p = Utils.getResourseInteger(getApplicationContext(),
					R.dimen.et_padding);
			view.setPadding(p, p, p, p);

			String msg = isCheckOutEmail ? Utils.getResourseString(this,
					R.string.msg_is_checking_email_available) : "";

			tvErrEmail.setText(msg);
			tvErrEmail.setVisibility(isCheckOutEmail ? View.VISIBLE
					: View.INVISIBLE);
			isEmailValid = true;
		} else {

			view.setBackgroundResource(isCheckOutEmail ? R.drawable.et_waiting
					: R.drawable.et_error);
			int p = Utils.getResourseInteger(getApplicationContext(),
					R.dimen.et_padding);
			view.setPadding(p, p, p, p);
			String msg = "";
			msg += isCheckOutEmail ? Utils.getResourseString(this,
					R.string.msg_is_checking_email_available) : "";

			if (!validEmailForm(view.getText().toString())) {
				msg += msg.length() > 0 ? "\n" : "";
				msg = Utils.getResourseString(getApplicationContext(),
						R.string.msg_email_invalid);
			}
			tvErrEmail.setText(msg);
			tvErrEmail.setVisibility(View.VISIBLE);
			isEmailValid = false;
		}
	}

	/**
	 * show on UI that email is used or not
	 */
	private void showEmailAvailable() {
		etEmail.setBackgroundResource(isEmailAvailable && isEmailValid ? R.drawable.et_valid
				: R.drawable.et_error);
		int p = Utils.getResourseInteger(getApplicationContext(),
				R.dimen.et_padding);
		etEmail.setPadding(p, p, p, p);

		String msg = "";
		msg += isEmailAvailable ? "" : Utils.getResourseString(this,
				R.string.msg_email_unavailable);

		if (!isEmailValid) {
			msg += msg.length() > 0 ? "\n" : "";
			msg = Utils.getResourseString(getApplicationContext(),
					R.string.msg_email_invalid);
		}

		tvErrEmail.setText(msg);
		tvErrEmail
				.setVisibility(isEmailAvailable && isEmailValid ? View.INVISIBLE
						: View.VISIBLE);
	}

	/**
	 * validate email form
	 * 
	 * @param email
	 *            email needed to be validated
	 * @return true if email form valid and false if not
	 */
	private boolean validEmailForm(String email) {
		int add = email.indexOf("@");
		if (add > 1) {
			int add2 = email.indexOf("@", add + 1);
			if (add2 == -1) {
				int dot = email.indexOf(".", add + 1);
				if (email.length() == dot || dot == -1)
					return false;
			} else
				return false;
		} else
			return false;
		return true;
	}

	/**
	 * checkOut will check valid user's informations before signing up
	 * 
	 * @return return true if all informations are valid or false if one of
	 *         those is not
	 */
	private boolean checkValidation() {

		validation(etFullName);
		validation(etUserName);
		validation(etPassword);
		validation(etConfirmPassword);
		validation(etEmail);

		if (isCheckOutUser)
			Utils.showToast(this, R.string.msg_is_checking_username_available);
		else if (isCheckOutEmail)
			Utils.showToast(this, R.string.msg_is_checking_email_available);
		else if (isFullNameValid && isUserAvailable) {
			if (isUserNameValid) {
				if (isPasswordValid) {
					if (isConfirmPasswordValid) {
						if (isEmailValid && isEmailAvailable) {
							return true;
						} else {
							etEmail.requestFocus();
						}
					} else {
						etConfirmPassword.requestFocus();
					}
				} else {
					etPassword.requestFocus();
				}
			} else {
				etUserName.requestFocus();
			}
		} else {
			etFullName.requestFocus();
		}
		return false;
	}

	/**
	 * checkOutUserName will check if user name is available or not
	 * 
	 * @param username
	 *            user name for login
	 * @return true if user name is not token or false if user name is token
	 */
	private boolean checkOutUserName(final String username) {
		QBAuth.createSession(new QBCallbackImpl() {
			@Override
			public void onComplete(Result result) {
				if (result.isSuccess()) {
					QBUsers.getUserByLogin(username, new QBCallbackImpl() {
						@Override
						public void onComplete(Result result) {
							isCheckOutUser = false;
							if (result.isSuccess()) {
								QBUserResult qbUserResult = (QBUserResult) result;

								isUserAvailable = false;

								Log.d("User", qbUserResult.getUser().toString());
							} else {
								isUserAvailable = true;
								Log.e("Errors", result.getErrors().toString());
							}
							showUsernameAvailable();
						}

					});
				} else {

				}
			}
		});
		return isUserAvailable;
	}

	/**
	 * checkOutEmail will check if user's email is available or not
	 * 
	 * @param email
	 *            user's email
	 * @return true if user's email is not token or false if user's email is
	 *         token
	 */
	private boolean checkOutEmail(final String email) {
		QBAuth.createSession(new QBCallbackImpl() {
			@Override
			public void onComplete(Result result) {
				if (result.isSuccess()) {
					QBUsers.getUserByEmail(email, new QBCallbackImpl() {
						@Override
						public void onComplete(Result result) {
							isCheckOutEmail = false;
							if (result.isSuccess()) {
								QBUserResult qbUserResult = (QBUserResult) result;

								isEmailAvailable = false;

								Log.d("User", qbUserResult.getUser().toString());
							} else {
								isEmailAvailable = true;
								Log.e("Errors", result.getErrors().toString());
							}
							showEmailAvailable();
						}

					});
				} else {

				}
			}
		});
		return isEmailAvailable;
	}
}
